static DMA1_INFOS: [[&'static str; 8]; 8] = [
    [
        "SPI3_RX",
        "I2C1_RX",
        "TIM4_CH1",
        "I2S3_EXT_RX",
        "UART5_RX",
        "UART8_TX",
        "TIM5_CH3/TIM5_UP",
        "",
    ], // S0
    [
        "",
        "",
        "",
        "TIM2_UP/TIM2_CH3",
        "USART3_RX",
        "UART7_TX",
        "TIM5_CH4/TIM5_TRIG",
        "TIM6_UP",
    ], // S1
    [
        "SPI3_RX",
        "TIM7_UP",
        "I2S3_EXT_RX",
        "I2C3_RX",
        "UART4_RX",
        "TIM3_CH4/TIM3_UP",
        "TIM5_CH1",
        "I2C2_RX",
    ], // S2
    [
        "SPI2_RX",
        "",
        "TIM4_CH2",
        "I2S2_EXT_RX",
        "USART3_TX",
        "UART7_RX",
        "TIM5_CH4/TIM5_TRIG",
        "I2C2_RX",
    ], // S3
    [
        "SPI2_TX",
        "TIM7_UP",
        "I2S2_EXT_TX",
        "I2C3_TX",
        "UART4_TX",
        "TIM3_CH1/TIM3_TRIG",
        "TIM5_CH2",
        "USART3_TX",
    ], // S4
    [
        "SPI3_TX",
        "I2C1_RX",
        "I2S3_EXT_TX",
        "TIM2_CH1",
        "USART2_RX",
        "TIM3_CH2",
        "",
        "DAC1",
    ], // S5
    [
        "",
        "I2C1_TX",
        "TIM4_UP",
        "TIM2_CH2/TIM2_CH4",
        "USART2_TX",
        "UART8_RX",
        "TIM5_UP",
        "DAC2",
    ], // S6
    [
        "SPI3_TX",
        "I2C1_TX",
        "TIM4_CH3",
        "TIM2_UP/TIM2_CH4",
        "UART5_TX",
        "TIM3_CH3",
        "",
        "I2C2_TX",
    ], // S7
];

static DMA2_INFOS: [[&'static str; 8]; 8] = [
    [
        "ADC1",
        "",
        "ADC3",
        "SPI1_RX",
        "SPI4_RX",
        "",
        "TIM1_TRIG",
        "",
    ],
    [
        "",
        "DCMI",
        "ADC3",
        "",
        "SPI4_TX",
        "USART6_RX",
        "TIM1_CH1",
        "TIM8_UP",
    ],
    [
        "TIM8_CH1/TIM8_CH2/TIM8_CH3",
        "ADC2",
        "",
        "SPI1_RX",
        "USART1_RX",
        "USART6_RX",
        "TIM1_CH2",
        "TIM8_CH1",
    ],
    [
        "", "ADC2", "SPI5_RX", "SPI1_TX", "SDIO", "SPI4_RX", "TIM1_CH1", "TIM8_CH2",
    ],
    [
        "ADC1",
        "",
        "SPI5_TX",
        "",
        "",
        "SPI4_TX",
        "TIM1_CH4/TIM1_TRIG/TIM1_COM",
        "TIM8_CH3",
    ],
    [
        "",
        "SPI6_TX",
        "CRYP_OUT",
        "SPI1_TX",
        "USART1_RX",
        "",
        "TIM1_UP",
        "SPI5_RX",
    ],
    [
        "TIM1_CH1/TIM1_CH2/TIM1_CH3",
        "SPI6_RX",
        "CRYP_IN",
        "",
        "SDIO",
        "USART6_TX",
        "TIM1_CH3",
        "SPI5_TX",
    ],
    [
        "",
        "DCMI",
        "HASH_IN",
        "",
        "USART1_TX",
        "USART6_TX",
        "",
        "TIM8_CH4/TIM8_TRIG/TIM8_COM",
    ],
];

pub struct DMAInfo {
    pub dma: u8,
    pub stream: u8,
    pub channel: u8,
}

impl DMAInfo {

    pub fn find(name: &str) -> Vec<DMAInfo> {
        let mut vec = Vec::new();

        for (stream_index, stream) in DMA1_INFOS.iter().enumerate() {
            for (channel_index, ch) in stream.iter().enumerate() {
                let ch = *ch;
                if DMAInfo::is_eq(ch, name) {
                    let info = DMAInfo {
                        dma: 1,
                        stream: stream_index as u8,
                        channel: channel_index as u8,
                    };
                    vec.push(info);
                }
            }
        }

        for (stream_index, stream) in DMA2_INFOS.iter().enumerate() {
            for (channel_index, ch) in stream.iter().enumerate() {
                let ch = *ch;
                if DMAInfo::is_eq(ch, name) {
                    let info = DMAInfo {
                        dma: 2,
                        stream: stream_index as u8,
                        channel: channel_index as u8,
                    };
                    vec.push(info);
                }
            }
        }

        vec
    }

    fn is_eq(ch: &str, name: &str) -> bool {
        if ch.is_empty() {
            return false;
        }
        if ch == name {
            return true;
        }
        let chs: Vec<&str> = ch.split("/").collect();
        for ch in chs {
            if ch == name {
                return true;
            }
        }
        false
    }
}
